﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AutoMapper;

using Revis.VClinicNet.Core.Domain;
using Revis.VClinicNet.Core.Domain.Repository;
using Revis.VClinicNet.App.Internal.Dto;
using Revis.VClinicNet.App.Internal.Dto.Validation;
using Revis.VClinicNet.Core.Domain.Factory;

namespace Revis.VClinicNet.App.Internal.ServiceImpl
{
    public class VisitService : IVisitService
    {
        private IVisitRepository _visitRepository = null;
        private IDoctorRepository _doctorRepository = null;
        private IPatientRepository _patientRepository = null;

        public VisitService(IVisitRepository ivr, IDoctorRepository idt, IPatientRepository ipr)
        {
            _visitRepository = ivr;
            _doctorRepository = idt;
            _patientRepository = ipr;
        }

        public long Create(VisitCreateDto visitCreateDto)
        {
            Validation.For<VisitCreateDto>().Using<VisitCreateDtoRules>().Check(visitCreateDto);

            Doctor doctor = _doctorRepository.Find(visitCreateDto.DoctorId);
            if (doctor == null) {
                throw new ClinicException("Nie znaleziono takiego lekarza");
            }
            Patient patient = _patientRepository.Find(visitCreateDto.PatientId);
            if (patient == null) {
                throw new ClinicException("Nie znaleziono takiego pacjenta");
            }
            long id = 0;
            try {
                VisitFactory factory = new VisitFactory();
                Visit visit = factory.Book(doctor, patient, visitCreateDto.Date);
                _visitRepository.Store(visit);
                id = visit.Id;
            } catch (ArgumentException ae) {
                throw new ClinicException(ae.Message);
            }
            return id;
        }

        public void Delete(long visitId)
        {
            Visit visit = _visitRepository.Find(visitId);
            if (visit != null) {
                _visitRepository.Delete(visit);
            }
        }

        public IList<VisitInfoDto> ListAllByDoctor(long doctorId)
        {
            IList<Visit> visits = _visitRepository.FindDoctorVisits(doctorId);
            IList<VisitInfoDto> visitsList = Mapper.Map<IList<Visit>, IList<VisitInfoDto>>(visits);
            return visitsList;
        }

        public IList<VisitInfoDto> ListAllByPatient(long patientId)
        {
            IList<Visit> visits = _visitRepository.FindPatientVisits(patientId);
            IList<VisitInfoDto> visitsList = Mapper.Map<IList<Visit>, IList<VisitInfoDto>>(visits);
            return visitsList;
        }

        public TDto Find<TDto>(long visitId)
        {
            Visit visit = _visitRepository.Find(visitId);
            TDto dto = Mapper.Map<Visit, TDto>(visit);
            return dto;
        }
    }
}
